/*
 * @Description: 模拟 ajax
 * @Version: 1.0.0
 * @Author: gyh
 * @Date: 2021-08-25 15:41:03
 * @LastEditors: gyh
 * @LastEditTime: 2021-08-25 16:47:35
 */
const http = {
  ajax(config = {}) {
    let _config = Object.assign(
      {
        url: '',
        type: 'GET',
        dataType: 'json',
        async: true,
        data: null,
        headers: {},
        timeout: 5000,
        beforeSend: xhr => {},
        success: (result, status, xhr) => {},
        error: (xhr, status, error) => {},
        complete: (xhr, status) => {},
      },
      config,
    )
    if (!_config.url || !_config.type || _config.async === undefined) return alert('参数有误')
    let xhr = new XMLHttpRequest()
    // 请求开始回调函数
    xhr.addEventListener('loadstart', e => {
      _config.beforeSend(xhr)
    })
    // 请求成功回调函数
    xhr.addEventListener('load', e => {
      const status = xhr.status
      if ((status >= 200 && status < 300) || status === 304) {
        let result
        if (xhr.responseType === 'text') {
          result = xhr.responseText
        } else if (xhr.responseType === 'document') {
          result = xhr.responseXML
        } else {
          result = xhr.response
        }
        _config.success(result, status, xhr)
      } else {
        _config.error(xhr, status, e)
      }
    })
    // 请求结束
    xhr.addEventListener('loadend', e => {
      _config.complete(xhr, xhr.status)
    })
    // 请求出错
    xhr.addEventListener('error', e => {
      _config.error(xhr, xhr.status, e)
    })
    // 请求超时
    xhr.addEventListener('timeout', e => {
      _config.error(xhr, 408, e)
    })
    // 请求类型参数处理
    let useUrlParams = false
    let type = _config.type.toUpperCase()
    if (type === 'GET' || type === 'DELETE') {
      useUrlParams = true
      _config.url += http.getUrlParams(_config.url, _config.data)
    }
    // 初始化请求
    xhr.open(_config.type, _config.url, _config.async)
    // 设置返回数据类型
    xhr.responseType = _config.dataType
    // 设置请求头
    for (const key of Object.keys(_config.headers)) {
      xhr.setRequestHeader(key, _config.headers[key])
    }
    // 设置超时时间
    if (_config.async && _config.timeout) {
      xhr.timeout = _config.timeout
    }
    // 发送请求
    xhr.send(useUrlParams ? null : http.getQueryData(_config.data))
  },

  // 把参数data转为url查询参数
  getUrlParams(url, data) {
    let paramsStr = ''
    if (data) {
      paramsStr = data instanceof Object ? http.getQueryString(data) : data
    }
    return url.indexOf('?') !== -1 ? paramsStr : `?${paramsStr}`
  },

  // 把对象转为查询字符串
  getQueryString(data) {
    let params = []
    if (data instanceof Object) {
      Object.keys(data).forEach(key => {
        // if (val instanceof Date) {}
        params.push(`${encodeURIComponent(key)}=${encodeURIComponent(data[key])}`)
      })
    }
    return params.join('&')
  },

  // 获取 ajax 请求参数
  getQueryData(data) {
    if (!data) return
    if (typeof data === 'string' || data instanceof FormData) return data
    return http.getQueryString(data)
  },
}
